﻿using System.ComponentModel;
using System.Runtime.Serialization;

using SharpGL.Media3D;

namespace SharpGL.SceneGraph.Transformations
{
    /// <summary>
    /// Base class for transformations.
    /// </summary>
    [DataContract(/*IsReference = true, */Name = "Transformation", Namespace = "SharpGL.SceneGraph")]
    public abstract class Transformation : INotifyPropertyChanged
    {
        #region Private Methods

        [OnDeserialized]
        private void OnDeserialized(StreamingContext ctx)
        {
            OnDeserialized();
        }

        [OnDeserializing]
        private void OnDeserializing(StreamingContext ctx)
        {
            OnDeserializing();
        }

        #endregion Private Methods

        #region Protected Methods

        /// <summary>
        /// Call this function to do the PropertyChanged event.
        /// </summary>
        protected void NotifyPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        protected virtual void OnDeserialized()
        {
        }

        protected virtual void OnDeserializing()
        {
        }
        
        #endregion Protected Methods

        #region Public Methods

        /// <summary>
        /// Performs the transformation on the current matrix.
        /// </summary>
        /// <param name="gl">The OpenGL instance.</param>
        public abstract void Transform(OpenGL gl);

        /// <summary>
        /// Reset to default state.
        /// </summary>
        public abstract void Reset();

        #endregion Public Methods

        #region Public Events

        [Description("Called when properties has been changed."), Category("SharpGL")]
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion Public Events

        #region Public Properties

        public virtual Matrix TransformationMatrix
        {
            get
            {
                return new Matrix(Matrix.Identity(4));
            }
        }

        #endregion Public Properties
    }
}
